package 队列;

import java.util.LinkedList;
import java.util.Queue;

/**
 * @author liucong
 * @date 2021/2/25 - 15:14
 *
 * 请你仅使用两个队列实现一个后入先出（LIFO）的栈，并支持普通队列的全部四种操作（push、top、pop 和 empty）。
 *
 * 实现 MyStack 类：
 *
 * void push(int x) 将元素 x 压入栈顶。
 * int pop() 移除并返回栈顶元素。
 * int top() 返回栈顶元素。
 * boolean empty() 如果栈是空的，返回 true ；否则，返回 false 。
 *  
 *
 * 注意：
 *
 * 你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。
 * 你所使用的语言也许不支持队列。 你可以使用 list （列表）或者 deque（双端队列）来模拟一个队列 , 只要是标准的队列操作即可。
 *
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/implement-stack-using-queues
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 */
public class _225_用队列实现栈 {
    public static void main(String[] args) {
        MyStack2 stack=new MyStack2();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        System.out.println(stack.top());
    }

    static class MyStack2 {
        private Queue<Integer> inQueue;
        private Queue<Integer> outQueue;

        /** Initialize your data structure here. */
        public MyStack2() {
            inQueue = new LinkedList<>();
            outQueue = new LinkedList<>();
        }

        /** Push element x onto stack. */
        public void push(int x) {
            inQueue.offer(x);
            while (!outQueue.isEmpty()){
                inQueue.offer(outQueue.poll());
            }
            Queue<Integer> tmp = outQueue;
            outQueue = inQueue;
            inQueue = tmp;
        }

        /** Removes the element on top of the stack and returns that element. */
        public int pop() {
            return outQueue.poll();
        }

        /** Get the top element. */
        public int top() {
            return outQueue.peek();
        }

        /** Returns whether the stack is empty. */
        public boolean empty() {
            return outQueue.isEmpty();
        }
    }

    static class MyStack1 {
        private Queue<Integer> inQueue;
        private Queue<Integer> outQueue;

        /** Initialize your data structure here. */
        public MyStack1() {
            inQueue = new LinkedList<>();
            outQueue = new LinkedList<>();
        }

        /** Push element x onto stack. */
        public void push(int x) {
            if(inQueue.isEmpty() && outQueue.isEmpty()){
                inQueue.offer(x);
            }else if(!inQueue.isEmpty()){
                inQueue.offer(x);
            }else if(!outQueue.isEmpty()){
                outQueue.offer(x);
            }
        }

        /** Removes the element on top of the stack and returns that element. */
        public int pop() {
            int res;
            if(!inQueue.isEmpty()){
                int size = inQueue.size()-1;
                for (int i = 0; i < size; i++) {
                    outQueue.offer(inQueue.poll());
                }
                res = inQueue.poll();
            }else{
                int size = outQueue.size()-1;
                for (int i = 0; i < size; i++) {
                    inQueue.offer(outQueue.poll());
                }
                res = outQueue.poll();
            }
            return res;
        }

        /** Get the top element. */
        public int top() {
            int res;
            if(!inQueue.isEmpty()){
                int size = inQueue.size()-1;
                for (int i = 0; i < size; i++) {
                    outQueue.offer(inQueue.poll());
                }
                res = inQueue.peek();
                outQueue.offer(inQueue.poll());
            }else{
                int size = outQueue.size()-1;
                for (int i = 0; i < size; i++) {
                    inQueue.offer(outQueue.poll());
                }
                res = outQueue.peek();
                inQueue.offer(outQueue.poll());
            }
            return res;
        }

        /** Returns whether the stack is empty. */
        public boolean empty() {
            return inQueue.isEmpty() && outQueue.isEmpty();
        }
    }

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack obj = new MyStack();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.top();
 * boolean param_4 = obj.empty();
 */
}
